<?php

class shopCartActions extends SXActions
{

    /**
     * add product to shop cart - in user session -
     * @param sfWebRequest $request
     * @return  sfView::NONE 
     * @author Mina.Gerges
     */
    public function executeAddProductToShopCart(sfWebRequest $request)
    {
        $this->forward404Unless($request->isXmlHttpRequest());
        $productId = $request->getParameter('pid');
        $quantity  = $request->getParameter('q');
        $this->checkProduct($productId);
        $shopCart  = $this->getUser()->getAttribute('shopCart', array());
        if (!$quantity)
        {
            // that is mean user sent quantity = 0 He want to remove this item
            unset($shopCart[$productId]);
        }
        else
        {
            // check quantity in integer and less than or equal sfConfing::get('app_shop_cart_max_qty')
            // add product to user shop cart
            if (is_numeric($quantity) && $quantity <= sfConfig::get('app_shop_cart_max_qty'))
            {
                $shopCart[$productId] = $quantity;
            }
            else
            {
                $this->getUser()->setFlash('message_failed', 'Maximum product number ' . sfConfig::get('app_shop_cart_max_qty'));
                // return error message
                return $this->renderJson(array('type' => 'message', 'html' => $this->getPartial('messages')));
            }
        }

        $this->getUser()->setAttribute('shopCart', $shopCart);
        return $this->renderComponent('shopCart', 'shopCartProductsList');
    }

    /**
     * remove product from shop cart - in user session -
     * @param sfWebRequest $request
     * @return  sfView::NONE 
     * @author Mina.Gerges
     */
    public function executeRemoveProductFromShopCart(sfWebRequest $request)
    {
        $this->forward404Unless($request->isXmlHttpRequest());
        $productId = $request->getParameter('pid');
        $this->checkProduct($productId);
        // remove product from user shop cart
        $shopCart  = $this->getUser()->getAttribute('shopCart', array());
        if ($shopCart[$productId])
        {
            // get the key of product in $shopCart array
            unset($shopCart[$productId]);
            $this->getUser()->setAttribute('shopCart', $shopCart);
            $returnVal = true;
        }
        else
        {
            $returnVal = false;
        }
        return $this->renderJson($returnVal);
    }

    /**
     * clear all products which added to shop cart
     * @author Mina.Gerges
     */
    public function executeClearShopCart()
    {
        $this->getUser()->setAttribute('shopCart', array());
        return $this->renderComponent('shopCart', 'shopCartProductsList');
    }

    /**
     * Show my selected products in shop cart
     */
    public function executeShowMyCart()
    {
        $items = $this->getUser()->getAttribute('shopCart', array());
        $this->items    = $items;
        $this->products = ProductTable::getInstance()->getAllProducts(array_keys($items))->execute();
    }

    /**
     * show list of products 
     */
    public function executeProducts()
    {
        $this->products = ProductTable::getInstance()->getAllProducts()->execute();
    }

    /**
     * Check out the shoping cart - payment step -
     * @param sfWebRequest $request
     */
    public function executeCheckOut(sfWebRequest $request)
    {
        // this page can access only by POST request
        $flag = true;
        if ($request->isMethod(sfWebRequest::POST) && $request->getReferer() == $this->generateUrl('ShowMyCart', array(), true))
        {
            // validate product exsit in data pase
            $this->validateShopCart();
            $productIds = array();
            $orderDetails = array();
            $quantity = $request->getParameter('quantity');
            if ($quantity && is_array($quantity))
            {
                foreach ($quantity as $k => $v)
                {
                    // insert into $orderDetails only valid proudcts which send from POST request
                    $productIds[]     = $k;
                    $orderDetails[$k] = array('product_id' => $k, 'quantity'   => $v);
                }
                $cartForm    = new CartForm(array(), array('productIds' => $productIds));
                $cartForm->bind($orderDetails);
                if ($cartForm->isValid())
                {
                    $this->getUser()->setAttribute('orderDetails', $orderDetails);
                }
                else
                {
                    // problem with data -my be the user try to send in valid quatity
                    $flag         = false;
                    $errorMessage = array('type'    => 'message_warning', 'message' => 'Sorry Error happends in your selected products , Please select it again');
                }
            }
            else
            {
                // that is mean no product selected to add to user
                $flag         = false;
                $errorMessage = array('type'    => 'message_warning', 'message' => 'no products selected');
            }
        }
        else
        {
            // that is mean the user try to access this page from Get reqeust - invalid process
            $flag         = false;
            $errorMessage = array('type'    => '', 'message' => '');
        }
        if (!$flag)
        {
            $this->getUser()->setFlash($errorMessage['type'], $errorMessage['message']);
            $this->redirect($this->generateUrl('ShowMyCart'));
        }
        $this->userOrderForm = new UserOrderForm();
        $this->CCForm        = new CreditCardForm();
    }

    /**
     * process the cart check out (pay the amount and create customer order record)
     * @param sfWebRequest $request
     */
    public function executeProcessCheckOut(sfWebRequest $request)
    {
        if ($request->isMethod(sfWebRequest::POST))
        {
            // validate product exsit in data pase
            $this->validateShopCart();
            // check if there are orderDetails in user session
            $orderDetails = $this->getUser()->getAttribute('orderDetails');
            if (!(is_array($orderDetails) && count($orderDetails) > 0))
            {
                // that is mean error in data so we need to go back to shop cart form
                $this->getUser()->setFlash('message_warning', 'no products selected');
                $this->redirect($this->generateUrl('ShowMyCart'));
            }
            // process order form
            $this->userOrderForm = new UserOrderForm();
            $this->userOrderForm->bind($request->getParameter($this->userOrderForm->getName()));
            $this->CCForm        = new CreditCardForm();
            $this->CCForm->bind($request->getParameter($this->CCForm->getName()));
            if ($this->userOrderForm->isValid() && $this->CCForm->isValid())
            {
                $productsIds = array();
                foreach ($orderDetails as $orderDetail)
                {
                    $productsIds[]  = $orderDetail['product_id'];
                }
                $prodcutsPrices = ProductTable::getInstance()->getProductPrices($productsIds);
                $totalPrice     = 0;

                //create order details records for each product
                foreach ($orderDetails as $orderDetail)
                {
                    $orderDetailsObject = new OrderDetails;
                    $orderDetailsObject->setProductId($orderDetail['product_id']);
                    $orderDetailsObject->setQuantity($orderDetail['quantity']);
                    $orderDetailsObject->setPrice($prodcutsPrices[$orderDetail['product_id']]);
                    $this->userOrderForm->getObject()->getOrderDetails()->add($orderDetailsObject);
                    $totalPrice+=($orderDetail['quantity'] * $prodcutsPrices[$orderDetail['product_id']]);
                }

                //perform the paymment via usaepay
                $trandactionResponse = $this->CCForm->payProducts($totalPrice);


                //save order details if the payment is successed
                if ($trandactionResponse)
                {
                    $this->userOrderForm->getObject()->setAddress($this->CCForm->getValue('address'));
                    $this->userOrderForm->getObject()->setZipCode($this->CCForm->getValue('zip_code'));
                    $this->userOrderForm->getObject()->setTransactionId($trandactionResponse->RefNum);
                    $this->userOrderForm->getObject()->setStatusCode($trandactionResponse->StatusCode);
                    $this->userOrderForm->save();
                    // remove products from session

                    $errorMessage = array('type'    => 'message_success', 'message' => 'Successful Payment!');
                }
                else
                {
                    $errorMessage = array('type'    => 'message_failed', 'message' => 'Payment Problem!');
                }
                // send Email to the owner of shop cart
                $owner    = SettingsTable::getInstance()->findAll()->getFirst();
                $mailer   = sfContext::getInstance()->getMailer();
                $message  = $mailer->compose(array($this->userOrderForm->getObject()->getEmail()=>'Shoping Cart'), $owner->getEmail(), 'Certifix Shopin Cart ,New Order Created Check Order Details',
                        'Kindly, Be informed that new request has been created with Id #'.$this->userOrderForm->getObject()->getId().' Please go to your admin area to process it');
                $mailer->send($message);
                // clear the shoping cart
                $this->getUser()->setAttribute('shopCart', array());

                $this->getUser()->setFlash($errorMessage['type'], $errorMessage['message']);
                $this->redirect($this->generateUrl('Products'));
            }
            else
            {
                $this->setTemplate('checkOut');
            }
        }
        else
        {
            // this request must be send from POST method if not redirect user to shoping cart
            $this->redirect($this->generateUrl('ShowMyCart'));
        }
    }

    /**
     * check if product exist if not forwar 404
     * @param integer $productId
     * @return Product 
     * @author  Mina Gerges
     */
    protected function checkProduct($productId)
    {
        $product = ProductTable::getInstance()->findOneById($productId);
        $this->forward404Unless($product);
        return $product;
    }

    /**
     * validate that the product in shoing cart exest in data base if not REDIRECT the user to products page
     * @author  Mina Gerges
     */
    protected function validateShopCart()
    {
        $shopCart = $this->getUser()->getAttribute('shopCart', array());
        if (count($shopCart) > 0)
        {
            // check that all products exist in database
            $prdocuts = ProductTable::getInstance()->getAllProducts(array_keys($shopCart))->execute();
            // check that the return products equal to products in shop cart
            if (count($shopCart) != count($prdocuts))
            {
                // that is mean there is deleted products so we clear user shop cart and redirect him to products page
                $this->getUser()->setAttribute('shopCart', array());
                $this->getUser()->setFlash('message_warning', 'Sorry , Problem happend in your selected product -my be some of prodcuts deleted- ,Please re selcet products again');
                $this->redirect($this->generateUrl('Products'));
            }
        }
    }

}